package xin.alum.aim;

import io.netty.channel.group.ChannelGroupFuture;
import io.netty.util.concurrent.GlobalEventExecutor;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
import xin.alum.aim.groups.SessionGroups;
import xin.alum.aim.groups.Sessions;
import xin.alum.aim.model.Pusher;
import xin.alum.aim.util.ApplicationContextUtil;

@Component
public class ClusterMessage implements xin.alum.aim.groups.ClusterMessage {
    private final Sessions sessions;
    /**
     * 日志对象
     */
    protected final InternalLogger logger = InternalLoggerFactory.getInstance(this.getClass());
    private int count;
    private final SessionGroups groups;

    public ClusterMessage(Sessions sessions, SessionGroups groups) {
        this.sessions = sessions;
        this.groups = groups;
    }

    @Override
    public void onMessage(byte[] b) {
        if (count++ % 1000 == 0) {
            logger.info("当前发送消息数：{}", count);
        }
        GlobalEventExecutor.INSTANCE.execute(() -> {
            StopWatch w = new StopWatch("ClusterMessage");
            w.start("deserialize");
            Jackson2JsonRedisSerializer json = ApplicationContextUtil.getBean(Jackson2JsonRedisSerializer.class);
            Pusher p = (Pusher) json.deserialize(b);
            w.stop();
            w.start("send");
            Sessions s = groups.get(p.getRecipient());
            ChannelGroupFuture f = s.sends(p.getData());
            f.addListener(t -> {
                long c = System.currentTimeMillis() - p.getData().getTimestamp();
                if (c > 200 || f.isPartialFailure()) {
                    logger.error("集群向【{}】群发【{}】人用时-{}", p.getRecipient(), s.size(), c);
                }
            });
            w.stop();
            if (w.getTotalTimeMillis() > 200) {
                logger.error("集群向【{}】群发【{}】人用时-{},\r\n{}", p.getRecipient(), s.size(), w.getTotalTimeMillis(), w.prettyPrint());
            }
        });
    }
}
